package org.dtrd.modules.dict.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.dtrd.modules.dict.entity.bean.DistrictInfoDTO;
import org.dtrd.modules.dict.entity.po.DtrdEntRdDicDistrict;
import org.dtrd.modules.dict.entity.vo.DistrictInfo;
import org.dtrd.modules.dict.entity.vo.DistrictInfoVO;
import org.dtrd.modules.dict.mapper.DtrdEntRdDicDistrictMapper;
import org.dtrd.modules.dict.service.IDtrdEntRdDicDistrictService;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author QR
 * @since 2021-12-06
 */
@Service
@DS("multi-datasource1")
@Slf4j
public class DtrdEntRdDicDistrictServiceImpl extends ServiceImpl<DtrdEntRdDicDistrictMapper, DtrdEntRdDicDistrict> implements IDtrdEntRdDicDistrictService {

    private DtrdEntRdDicDistrictMapper dtrdEntRdDicDistrictMapper;

    @Override
    public List<DistrictInfoDTO> getDistrictInfoList(Integer requestId) {
        LambdaQueryWrapper<DtrdEntRdDicDistrict> queryWrapper = baseQueryWrapper();
        List<DtrdEntRdDicDistrict> poList = list(queryWrapper);
        List<DistrictInfoDTO> dtoList = new ArrayList<>(poList.size());
        if (!poList.isEmpty()) {
            dtoList = poList.stream()
                    .map(po -> new DistrictInfoDTO().parseFromPo(po))
                    .collect(Collectors.toList());
        }
        return dtoList;
    }

    @Override
    public DistrictInfoDTO getDistrictInfo(Integer dataId) {
        DtrdEntRdDicDistrict dtrdEntRdDicDistrict = getById(dataId);
        return Optional.ofNullable(dtrdEntRdDicDistrict)
                .map(po -> new DistrictInfoDTO().parseFromPo(po))
                .orElse(null);
    }

    @Override
    public boolean saveOrUpdateDistrictInfo(DistrictInfoDTO dto) {
        DtrdEntRdDicDistrict dtrdEntRdDicDistrict = new DtrdEntRdDicDistrict();
        if (dto.getDataId() == null) {
            dtrdEntRdDicDistrict = dtrdEntRdDicDistrict.init();
        }
        dtrdEntRdDicDistrict.parseFromDto(dto);
        return saveOrUpdate(dtrdEntRdDicDistrict);
    }

    @Override
    public boolean removeDistrictInfo(Integer dataId) {
        return removeById(dataId);
    }

    @Override
    public String getDistrictNameByAreaId(Integer areaId) {
        LambdaQueryWrapper<DtrdEntRdDicDistrict> queryWrapper = baseQueryWrapper()
                .eq(DtrdEntRdDicDistrict::getDistrictInfoDiId, areaId)
                .last("limit 1");
        DtrdEntRdDicDistrict dicDistrictInfo = getOne(queryWrapper);
        return Optional.ofNullable(dicDistrictInfo).map(DtrdEntRdDicDistrict::getDistrictInfoDiName).orElse(null);
    }

    @Override
    public DistrictInfoVO getDistrict() {
        List<Integer> parentIdList = new ArrayList<>(10);
        parentIdList.add(0);
        List<DtrdEntRdDicDistrict> provincePoList = baseMapper.getDistrictList(parentIdList);
        // 省份
        parentIdList.clear();
        provincePoList.stream().map(DtrdEntRdDicDistrict::getDistrictInfoDiId).forEach(parentIdList::add);
        // 城市
        List<DtrdEntRdDicDistrict> cityPoList = baseMapper.getDistrictList(parentIdList);
        parentIdList.clear();
        provincePoList.stream().map(DtrdEntRdDicDistrict::getDistrictInfoDiId).forEach(parentIdList::add);
        // 地区
        List<DtrdEntRdDicDistrict> regionPoList = baseMapper.getDistrictList(parentIdList);
        parentIdList.clear();
        provincePoList.stream().map(DtrdEntRdDicDistrict::getDistrictInfoDiId).forEach(parentIdList::add);
        // 设置返回值
        DistrictInfoVO districtInfoVO = new DistrictInfoVO();
        districtInfoVO.setProvinceInfo(provincePoList.stream().map(DistrictInfo::new).collect(Collectors.toList()));
        districtInfoVO.setCityInfo(cityPoList.stream().map(DistrictInfo::new).collect(Collectors.toList()));
        districtInfoVO.setPrefectureInfo(regionPoList.stream().map(DistrictInfo::new).collect(Collectors.toList()));
        return districtInfoVO;
    }

    @Override
    public List<DistrictInfo> listProvinceInfo() {
        LambdaQueryWrapper<DtrdEntRdDicDistrict> queryWrapper = baseQueryWrapper()
                .eq(DtrdEntRdDicDistrict::getDistrictInfoParentId, 0);
        // 省级信息
        List<DtrdEntRdDicDistrict> provincePoList = list(queryWrapper);
        return Optional.ofNullable(provincePoList)
                .map(list -> list.stream().map(DistrictInfo::new).collect(Collectors.toList()))
                .orElse(null);
    }

    @Override
    public List<DistrictInfo> listCityInfo(Integer provinceId) {
        LambdaQueryWrapper<DtrdEntRdDicDistrict> queryWrapper = baseQueryWrapper()
                .eq(DtrdEntRdDicDistrict::getDistrictInfoParentId, provinceId);
        // 市级信息
        List<DtrdEntRdDicDistrict> provincePoList = list(queryWrapper);
        return Optional.ofNullable(provincePoList)
                .map(list -> list.stream().map(DistrictInfo::new).collect(Collectors.toList()))
                .orElse(null);
    }

    @Override
    public String getDistrictNameById(Integer id) {
        LambdaQueryWrapper<DtrdEntRdDicDistrict> queryWrapper = baseQueryWrapper()
                .eq(DtrdEntRdDicDistrict::getDistrictInfoDiId, id)
                .last("limit 1");
        DtrdEntRdDicDistrict districtInfo = getOne(queryWrapper);
        return Optional.ofNullable(districtInfo)
                .map(DtrdEntRdDicDistrict::getDistrictInfoDiName)
                .orElse(null);
    }


    public LambdaQueryWrapper<DtrdEntRdDicDistrict> baseQueryWrapper() {
        return Wrappers.lambdaQuery(DtrdEntRdDicDistrict.class)
                .eq(DtrdEntRdDicDistrict::getIsDel, 0);
    }

    public LambdaUpdateWrapper<DtrdEntRdDicDistrict> baseUpdateWrapper() {
        return Wrappers.lambdaUpdate(DtrdEntRdDicDistrict.class)
                .eq(DtrdEntRdDicDistrict::getIsDel, 0);
    }
}
